/****************************************************************************/
/* NAME:           osmolator.c                                              */
/* PURPOSE:        Osmolator management                                     */
/* CREATED_BY:     Vyx                                                      */
/* CREATION_DATE:  07/05/2012                                               */
/************************************** (C) Copyright 2012 AquaLink *********/

#include "osmolator.h"
#include "Hal_InputManagement.h"
#include "Hal_OutputManagement.h"

/* Plug sensor level between Vcc and its gpio */
/* True sensor hight position                 */
/* False sensor low position                  */

/* SENSOR LOW and HIGH
 TRUE  FALSE
        ___
  |    |   |
 _|_   |___|
|   |    |
|___|    |

*/

/* SENSOR RESERVE
 FALSE  TRUE
        ___
  |    |   |
 _|_   |___|
|   |    |
|___|    |

*/

#ifdef _OSMOLATOR

#define Osmo_TASK_DELAY    (5000) /* 5s */

/**
  * @brief  Start the pump output.
  * @param  none
  * @retval None
  */
#define Osmo_StartPump()   (OUTPUT_SetOutputValue(OSMOLATOR_PUMP, TRUE))

/**
  * @brief  Stop the pump output.
  * @param  none
  * @retval None
  */
#define Osmo_StopPump()    (OUTPUT_SetOutputValue(OSMOLATOR_PUMP, FALSE))

static Osmo_Sensor_Mode_t Osmo_SensorMode;
static Osmo_Water_level_t WaterLevel;

/**
  * @brief  Main function of osmolator module.
  * @param  none
  * @retval None
  */
void vTaskCTRL_OSMOLATOR()
{
    portTickType       xLastWakeTime;


    /* change default MODE */
    Osmo_SensorMode  = TWO_SENSOR_WITH_RESERVE;

    /* init */
    xLastWakeTime    = xTaskGetTickCount();
    WaterLevel       = OSMO_HIGH_LEVEL;

    while(1)
    {
        /* if reserve water is NOT empty */
        if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_RESERVE) == TRUE) ||
            (Osmo_SensorMode == ONE_SENSOR_WITHOUT_RESERVE)         ||
            (Osmo_SensorMode == TWO_SENSOR_WITHOUT_RESERVE))
        {
            /* ckeck the water level */
            if ((Osmo_SensorMode == ONE_SENSOR_WITHOUT_RESERVE) ||
                (Osmo_SensorMode == ONE_SENSOR_WITH_RESERVE))
            {
                /* with one sensor */
              WaterLevel = Osmo_CheckWaterLevel_OneSensor();
            }
            else
            {
                /* with two sensor */
              WaterLevel = Osmo_CheckWaterLevel_TwoSensor();
            }

            /* if manual mode */
            if (INPUT_GetInputValue(OSMOLATOR_MANUAL_START) == TRUE)
            {
                /* protection to start pump only if water level is not high */
                if (WaterLevel != OSMO_HIGH_LEVEL)
                {
                    Osmo_StartPump();
                }
            }
            /* if auto mode */
            else
            {
                switch(WaterLevel)
                {
                    case OSMO_LOW_LEVEL:
                    {
                        /* start pump if is not start */
                        if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_RESERVE) == TRUE) &&
                            (OUTPUT_GetOutputValue(OSMOLATOR_PUMP)         == FALSE))
                        {
                            Osmo_StartPump();
                        }
                        break;
                    }
                    case OSMO_MIDDLE_LEVEL:
                    {
                        break;
                    }
                    case OSMO_HIGH_LEVEL:
                    default:
                    {
                        /* stop pump if is start */
                        if (OUTPUT_GetOutputValue(OSMOLATOR_PUMP) == TRUE)
                        {
                            Osmo_StopPump();
                        }
                        break;
                    }
                }
            }
        }
        /* if reserve water is empty */
        else
        {
            if (OUTPUT_GetOutputValue(OSMOLATOR_PUMP) == TRUE)
            {
                Osmo_StopPump();
            }
        }

        wait(Osmo_TASK_DELAY);
    } /* Never exit this loop */
}

/**
  * @brief  Check the water level with two sensor.
  * @param  none
  * @retval Level of water (low,middle,high)
*/
Osmo_Water_level_t Osmo_CheckWaterLevel_TwoSensor(void)
{
  Osmo_Water_level_t Level;

  if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_LOW)  == FALSE) &&
      (INPUT_GetInputValue(OSMOLATOR_SENSOR_HIGH) == FALSE))
  {
    Level = OSMO_HIGH_LEVEL;
  }
  else if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_LOW)  == FALSE) &&
           (INPUT_GetInputValue(OSMOLATOR_SENSOR_HIGH) == TRUE))
  {
    Level = OSMO_MIDDLE_LEVEL;
  }
  else if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_LOW)  == TRUE) &&
           (INPUT_GetInputValue(OSMOLATOR_SENSOR_HIGH) == FALSE))
  {
    Level = OSMO_LOW_LEVEL;
  }
  else if ((INPUT_GetInputValue(OSMOLATOR_SENSOR_LOW)  == TRUE) &&
           (INPUT_GetInputValue(OSMOLATOR_SENSOR_HIGH) == TRUE))
  {
    Level = OSMO_LOW_LEVEL;
  }
  else
  {
    /* if default case occur, we considered that level is high, so pump is not started */
    Level = OSMO_HIGH_LEVEL;
  }

  return (Level);
}

/**
  * @brief  Check the water level with one sensor.
  * @param  none
  * @retval Level of water (low,high)
*/
Osmo_Water_level_t Osmo_CheckWaterLevel_OneSensor(void)
{
  Osmo_Water_level_t Level;

  if (INPUT_GetInputValue(OSMOLATOR_SENSOR_LOW) == FALSE)
  {
    Level = OSMO_HIGH_LEVEL;
  }
  else
  {
    Level = OSMO_HIGH_LEVEL;
  }

  return (Level);
}

/**
  * @brief  Set osmolator mode
  * @param  none
  * @retval none
*/
void Osmo_SetMode(uint8_t SensorMode, uint8_t reserve)
{
  if (SensorMode == 1 && reserve == 0)
  {
    Osmo_SensorMode = ONE_SENSOR_WITHOUT_RESERVE;
  }
  if (SensorMode == 1 && reserve == 1)
  {
    Osmo_SensorMode = ONE_SENSOR_WITH_RESERVE;
  }
  if (SensorMode == 2 && reserve == 0)
  {
    Osmo_SensorMode = TWO_SENSOR_WITHOUT_RESERVE;
  }
  if (SensorMode == 2 && reserve == 1)
  {
    Osmo_SensorMode = TWO_SENSOR_WITH_RESERVE;
  }
  else
  {
    Osmo_SensorMode = OFF_MODE;
  }
}

/**
  * @brief  Check water level
  * @param  none
  * @retval none
*/
uint8_t Osmo_GetWaterLevel(void)
{
  return (WaterLevel);
}

#endif /* _OSMOLATOR */
